﻿#region Copyright(c) 1998-2013, Arnaud Colin Licence GNU GPL version 3
/* Copyright(c) 1998-2013, Arnaud Colin
 * All rights reserved.
 *
 * Licence GNU GPL version 3
 * 
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 *   -> Redistributions of source code must retain the above copyright
 *      notice, this list of conditions and the following disclaimer.
 *
 *   -> Redistributions in binary form must reproduce the above copyright
 *      notice, this list of conditions and the following disclaimer in the
 *      documentation and/or other materials provided with the distribution.
 */
#endregion

using System;
using System.Collections.Generic;
#if NET35
using System.Linq;
#endif
using System.Runtime.CompilerServices;
using System.Text;
#if NET45
using System.Threading.Tasks;
#endif

namespace XoLib.Convertion
{
    
    /// <summary>
    /// 
    /// <example>  </example>/// 
    /// </summary>
    public class ByteToChar 
    {

        /// <summary>
        /// <para>
        /// <param name="buf">byte[]</param>
        /// <param name="Start">int</param>
        /// <param name="length">int?</param>
        /// </para>
        /// convert the Byte[] to char[]
        /// <example> ByteToString.GetArray("0104",0,4); </example>/// 
        /// <returns>Byte[]</returns>
        /// </summary>
#if !WindowsCE
        public static string GetArray(byte[] buf, int Start = 0, int? length = null)
#else
        public static string GetArray( byte[] buf , int Start, int? length)
#endif

         {
             int? _Length = null;


            if(length.HasValue)
            {
                if( length <= buf.Length)
                    _Length = length;
                else
                    _Length = buf.Length;
            }
            else
                _Length = buf.Length;

             if (!_Length.HasValue)
                 return null;

             string stemp = string.Empty;
             //char[] ArrChar = new char[_Length.Value];

             int count = 0;
             for (int i = Start; i < _Length.Value; i++)
             {
                 stemp += (char)buf[i];
                 count++;
             }

             return stemp;
         }
    }


    /// <summary>
    /// Class for convert IpAddress
    /// <example> IPAddress.LongToString(); IPAddress.StringToLong("192.168.1.1"); </example>/// 
    /// </summary>
    public class IPAddress : StringAndLong
    {
        /// <summary>
        /// <para>
        /// <param name="val">long</param>
        /// </para>
        /// convert the long in string 
        /// <example> IPAddress.LongToString(); </example>/// 
        /// <returns>string</returns>
        /// </summary>
#if  NET45
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
#endif
        public static string LongToString(long val)
        {
            
            return LongToString(val, 4, '.', 10);
            
        }

        /// <summary>
        /// <para>
        /// <param name="val">string</param>
        /// </para>
        /// convert the string in long
        /// <example> IPAddress.StringToLong("192.168.1.1") </example>/// 
        /// <returns>long</returns>
        /// </summary>
#if  NET45
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
#endif
        public static long StringToLong(string val)
        {
            return StringToLong(val, '.', 10);
        }
    }

    /// <summary>
    /// Class for convert MacAddress
    /// <example> MacAddress.StringToLong("00:17:23:14:32:75:00:00"); </example>/// 
    /// </summary>
    public class MacAddress : StringAndLong
    {
        /// <summary>
        /// <para>
        /// <param name="val">long</param>
        /// </para>
        /// convert the long in string 
        /// <example> MacAddress.LongToString(); </example>/// 
        /// <returns>string</returns>
        /// </summary>
#if  NET45
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
#endif
        public static string LongToString(long val)
        {
            return LongToString(val, 8, ':', 16);
        }

        /// <summary>
        /// <para>
        /// <param name="val">string</param>
        /// </para>
        /// convert the string in long
        /// <example> MacAddress.StringToLong("00:17:23:14:32:75:00:00") </example>/// 
        /// <returns>long</returns>
        /// </summary>
#if  NET45
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
#endif
        public static long StringToLong(string val)
        {
            return StringToLong(val, ':', 16);
        }
    }

    /// <summary>
    /// Class convert string to long and long to string
    /// </summary>
    public class StringAndLong
    {
        /// <summary>
        /// <para>
        /// <param name="val">string</param>
        /// <param name="Count">int</param>
        /// <param name="sp">char</param>
        /// <param name="ibase">int</param>
        /// </para>
        /// convert the long in string 
        /// <example> sample.LongToString(val, 8, ':', 16); </example>/// 
        /// <returns>string</returns>
        /// </summary>
        public static string LongToString(long val, int Count, char sp, int ibase)
        {
            long mask = 0xFF;
            string ip = string.Empty;
            string format = string.Empty;

            for (int i = 0; i < Count; i++)
            {

                long vt1 = (mask << (8 * i));
                byte num = (byte)((val & vt1) >> (8 * i));


                if (ibase == 16)
                    format = "X2";
                else
                    format = "d";


                if (i == 0)

                    ip = num.ToString(format);

                else

                    ip = ip + sp + num.ToString(format);

            }

            return ip;

        }

        /// <summary>
        /// <para>
        /// <param name="val">string</param>
        /// <param name="sp">char</param>
        /// <param name="ibase">int</param>
        /// </para>
        /// convert the string in long
        /// <example> StringToLong(val, ':', 16); </example>/// 
        /// <returns>long</returns>
        /// </summary>
        public static long StringToLong(string val, char sp, int ibase)
        {
            string[] ipBytes;
            long num = 0;

            if (!string.IsNullOrEmpty(val))
            {

                ipBytes = val.Split(sp);

                for (int i = 0; i < ipBytes.Length; i++)
                {                 
                    long vt1 = (long)Convert.ToByte(ipBytes[i], ibase);
                    int vt2 = (int)(8 * i);
                    num += (vt1 << vt2);
                }

            }
            return (long)num;
        }

    }   
}
